<template>
    <div class="content-list">
        <div class="title">投稿说明</div>
        <div class="article-content" v-html="contents.textCopy"></div>
        <div class="membership-apply">
            <div class="container">
                <!-- 标题 -->
                <h1 class="title">我要投稿</h1>
                <!-- 上传部分 -->
                <div class="form-section">
                    <el-form ref="formRef" :model="form" label-width="150px">
                        <div class="content" v-for="item in customObj.customList" :key="item.code">
                            <template v-if="item.type === 'select'">
                                <el-form-item :label="item.name" :prop="item.code" :rules="generateRules(item)">
                                    <el-select v-model="form[item.code]" placeholder="请选择投稿内容类型">
                                        <el-option v-for="i in item.dictList" :label="i.name"
                                            :value="i.value"></el-option>
                                    </el-select>
                                </el-form-item>
                            </template>
                            <template v-if="item.type === 'text'">
                                <el-form-item :label="item.name" :prop="item.code" :rules="generateRules(item)">
                                    <el-input v-model="form[item.code]"></el-input>
                                </el-form-item>
                            </template>
                            <template v-if="item.type === 'date'">
                                <el-form-item :label="item.name" :prop="item.code" :rules="generateRules(item)">
                                    <el-date-picker type="date" placeholder="选择日期" v-model="form[item.code]"
                                        style="width: 100%;"></el-date-picker>
                                </el-form-item>
                            </template>
                            <template v-if="item.type === 'fileUpload'">
                                <el-form-item :label="item.name" :prop="item.code">
                                    <el-upload class="upload-demo" :auto-upload="false"
                                        :on-change="(file) => handleFileSelect(file, item.code)" :show-file-list="true"
                                        limit="1" :file-list="fileList">
                                        <el-button size="medium" type="primary">{{ item.name }}</el-button>
                                        <!-- <div slot="tip" class="el-upload__tip">只能上传PDF/DOCX/TEXT文件</div> -->
                                    </el-upload>
                                </el-form-item>
                            </template>
                        </div>
                        <div class="submitbtn" @click="handleSubmit">我要投稿</div>
                    </el-form>
                </div>
            </div>
        </div>
    </div>
</template>

<script setup>
const { $fetchAuth } = useNuxtApp()

const props = defineProps({
    contents: {
        type: Object,
        default: () => ({})
    },
    type: {
        type: String,
        default: 'common'
    },
    prevtype: {
        type: String,
        default: 'about'
    }
})

const customObj = ref({})

const form = ref({})
const formRef = ref(null);
const fileList = ref([]);
// 生成动态验证规则
const generateRules = (item) => {
    const rules = []
    if (item.required) {
        rules.push({
            required: true,
            message: `${item.name}不能为空`,
            trigger: ['select', 'date'].includes(item.type) ? 'change' : 'blur'
        })
    }

    // 添加类型校验
    if (item.dataType === 'number') {
        rules.push({
            type: 'number',
            message: '必须输入数字',
            transform: value => Number(value)
        })
    }

    // 添加正则校验
    if (item.pattern) {
        rules.push({
            pattern: new RegExp(item.pattern),
            message: item.patternMsg || '格式不正确'
        })
    }

    return rules
}

//主动初始化表单字段
watch(() => customObj.value.customList, (newList) => {
    if (!newList) return
    newList.forEach(item => {
        item.required = true;
    })
    form.value = newList.reduce((acc, item) => {
        acc[item.code] = item.type === 'fileUpload' ? null : ''
        return acc
    }, {})
}, { immediate: true, deep: true })

// 获取表单值方法
const getFormValues = () => {
    return new Promise((resolve, reject) => {
        formRef.value.validate(valid => {
            if (valid) {
                // 深度拷贝表单值
                const formData = JSON.parse(JSON.stringify(form.value))
                resolve(formData)
            } else {
                reject(new Error('表单验证失败'))
            }
        })
    })
}

const handleSubmit = async () => {
    try {
        const values = await getFormValues()
        // 验证文件字段是否为字符串
        Object.entries(values).forEach(([key, value]) => {
            if (value === null || value === '') {
                throw new Error(`${key} 字段需要上传文件`)
            }
        })
        const res = await $fetchAuth(`${customObj.value.submitPath}`, {
          method: 'POST',
          body: {
            formId: props.contents.formModelId,
            // 文章id
            articleId: props.contents.id,
            ...form.value
          }
        })
        if(res.data.status === 0) {
            ElMessage.success('提交成功')
            formRef.value.resetFields()
            fileList.value = []
        }
    } catch (error) {
        ElMessage.error(error.message || '表单验证失败')
        console.error('验证错误详情:', error)
    }
}

const handleFileSelect = (file, fieldName) => {
    const fileBolb = file.raw;

    // 调用上传接口获取文件路径
    uploadFile(fileBolb).then(res => {
        const fileArray = [];
        fileArray.push(res.data);
        form.value[fieldName] = fileArray;
    }).catch(err => {
        ElMessage.error('文件上传失败');
        form.value[fieldName] = '';
    });
}

const uploadFile = async (file) => {
    const formData = new FormData();
    formData.append('file', file);
    try {
        return await $fetchAuth('/app/api/upload/file-upload', {
            method: 'POST',
            body: formData
        });
    } catch (error) {
        throw new Error('文件上传失败');
    }
}


watch(() => props.contents, async (newType) => {
    if (!newType.formModelId) return
    const res = await $fetchAuth(`/app/api/core/form/${newType.formModelId}`, {
        method: 'GET'
    })
    customObj.value = res.data;
},
    {
        immediate: true,
        deep: true
    }
);
</script>

<style lang="scss" scoped>
@use '@/assets/scss/main' as *;
$bg-color: #f9fafb;
$primary-blue: #1867CA;
$hover-blue: rgba(24, 103, 202, .8);
$success-bg: #dcfce7;
$success-text: #166534;
$error-bg: #fee2e2;
$error-text: #b91c1c;
$shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);

.membership-apply {

    .container {
        padding: 1rem 0 1.5rem;
        margin: 0 auto;
    }

    .form-section {
        :deep(.el-upload__tip) {
            margin-left: 1rem;
        }
        :deep(.el-form-item__label) {
            font-size: 1rem;
        }
    }

    .subtitle {
        color: #333333;
        font-size: .9rem;
        margin-bottom: 2rem;
    }

    .submitbtn {
        background: #1867CA;
        width: 14rem;
        padding: 0.6rem 0;
        color: #fff;
        border-radius: 0.3125rem;
        margin: auto;
        cursor: pointer;
        margin-top: 4rem;
        text-align: center;
    }

}

.content-list {
    --border-color: #F6F6F6;
    --text-color: #333333;
    --date-color: #999999;
    --hover-color: #1867CA;

    .title {
        position: relative;
        font-size: 1.2rem;
        font-weight: 600;
        color: $myprimary-color;
        // line-height: 28px;
        padding: 0 0 1.2rem 0;
        margin: 0 0 0 1rem;

        &::after {
            content: '';
            position: absolute;
            width: 3px;
            height: 1.3rem;
            background: $myprimary-color;
            top: 2px;
            left: -1rem;
        }
    }

    .article-content {
        font-size: .9rem;
        line-height: 1.6;
        color: var(--text-color);
        padding: 0rem 0 1.5rem;
        border-bottom: 1px solid var(--border-color);
    }

    .submit-content {
        padding: 1rem 0;
    }
    
    @media screen and (max-width: 768px) {
        .title {
            font-size: 1rem;

            &::after {
                height: 1.2rem;
            }
        }
    }
}
</style>